/*@A (C) 1992 Allen I. Holub                                                */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "switch.h"
#include "iCode.h"
#include "Parser.h"
extern char labelbuffer[MAX_LENGTH_BUFFER];
extern int NestLevel;
/*----------------------------------------------------------------------*/

stab  *new_stab(operand	*val, int	label)
{
    stab *p;

    if( !(p = (stab *) malloc(sizeof(stab)) ))
    {
		SYNTAX_ERROR;
		exit( 1 );
    }
    p->cur = p->table ;
    p->stab_label = label;
    p->def_label  = 0;
    p->op = val;
    return p;
}

/*----------------------------------------------------------------------*/

void	add_case(stab *p, operand *on_this, int go_here )
{
    /* Add a new case to the stab at top of stack. The `cur` field identifies
     * the next available slot in the dispatch table.
     */

    if( p->cur  >  &(p->table[CASE_MAX-1]) )
		SYNTAX_ERROR;
    else
    {
		p->cur->on_this = on_this ;
		p->cur->go_here = go_here;
		++( p->cur );
    }
}

/*----------------------------------------------------------------------*/

void	add_default_case(stab *p, int go_here)
{
    /* Add the default case to the current switch by remembering its label */
    if( p->def_label )
	{
		SYNTAX_ERROR;
	}
    p->def_label = go_here;
}

/*----------------------------------------------------------------------*/

void	gen_stab_and_free_table(stab *p)
{
    case_val	*cp;
	sprintf(labelbuffer, "%s%d", L_SWITCH, p->stab_label + 1);
	geniCodeGotoFromName(labelbuffer);
	sprintf(labelbuffer, "%s%d", L_SWITCH, p->stab_label);
	geniCodeLabelFromName(labelbuffer);
    //gen( "goto%s%d", L_SWITCH, p->stab_label + 1 );
    //gen( ":%s%d",    L_SWITCH, p->stab_label     );

    for( cp = p->table ; cp < p->cur ; ++cp )
    {
		//gen( "EQ%s%d", 	 p->name,  cp->on_this );
		//gen( "goto%s%d", L_SWITCH, cp->go_here );
		symbol *_trueLab;
		operand *tmp;
		if (!p->op)
			return;
		tmp = geniCodeLogic(p->op, cp->on_this, EQ_OP);
		sprintf(labelbuffer, "%s%d", L_SWITCH, cp->go_here);
		_trueLab = newSymbol(labelbuffer, NestLevel);
		geniCodeIfx(tmp, _trueLab, NULL); 
    }

    if( p->def_label )
	{
		//gen( "goto%s%d", L_SWITCH, p->def_label );
		sprintf(labelbuffer, "%s%d", L_SWITCH, p->def_label);
		geniCodeGotoFromName(labelbuffer);
	}

    //gen( ":%s%d", L_SWITCH, p->stab_label + 1 );
	sprintf(labelbuffer, "%s%d", L_SWITCH, p->stab_label + 1);
	geniCodeLabelFromName(labelbuffer);
    //free( p );
}

